﻿using System.Collections.Generic;
using Medicalsystem.MCP.FormDesigner.Common;
using Medicalsystem.MCP.FormDesigner.Interface;
using Medicalsystem.MCP.FormDesigner.Property;

namespace Medicalsystem.MCP.FormDesigner
{
    public class XML
    {
        /// <summary>
        /// 模板 生成XML
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string ModelToXML(ModelDesign model)
        {
            ModelPropertyXML modelXML = new ModelPropertyXML(model.ModelForm);

            return "<Model> " +
                      "<Property>" + modelXML.ToXML() + "</Property>" +
                      "<Controls>" + ControlsToXML(model.CtrlUIContainerHandler) + "</Controls>" +
                      "<ComControls>" + ControlsToXML(model.CtrlComContainerHandler) + "</ComControls>" +
                   "</Model>";
        }

        /// <summary>
        /// XML 生成模板
        /// </summary>
        /// <param name="XML"></param>
        /// <param name="model"></param>
        public static void XMLToModel(string XML, ModelDesign model)
        {
            if (XML.Length > 0)
            {
                System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                doc.LoadXml(XML);

                XMLToModel(doc, model);
            }
        }

        /// <summary>
        /// XML 生成模板
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="model"></param>
        public static void XMLToModel(System.Xml.XmlDocument doc, ModelDesign model)
        {
            foreach (System.Xml.XmlNode XN in doc.DocumentElement.ChildNodes)
            {
                switch (XN.Name.ToLower())
                {
                    case "property":
                        ModelPropertyXML modelXML = new ModelPropertyXML(model.ModelForm);
                        modelXML.FromXML(XN.ChildNodes);
                        break;

                    case "controls":
                        foreach (System.Xml.XmlNode xn in XN.ChildNodes)
                        {
                            XMLToControl(xn, model.CtrlUIContainerHandler, model);
                        }
                        break;

                    case "comcontrols":
                        foreach (System.Xml.XmlNode xn in XN.ChildNodes)
                        {
                            XMLToControl(xn, model.CtrlComContainerHandler, model);
                        }
                        break;

                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// 控件生成 XML - 主要用于复制粘贴
        /// </summary>
        /// <param name="ctrls"></param>
        public static string ControlsToXML(List<CtrlMngDesign> ctrls)
        {
            string strUI = string.Empty;
            string strCom = string.Empty;

            foreach (CtrlMngDesign ctrl in ctrls)
            {
                if (ctrl.Owner is ICtrlUI)
                {
                    strUI += "<Control id=\"" + ((ICtrlBase)ctrl.Owner).CtrlID + "\">" + ControlToXML(ctrl) + "</Control>";
                }
                else
                {
                    strCom += "<Control id=\"" + ((ICtrlBase)ctrl.Owner).CtrlID + "\">" + ControlToXML(ctrl) + "</Control>";
                }
            }

            return "<Model> " +
                    "<Controls>" + strUI + "</Controls>" +
                    "<ComControls>" + strCom + "</ComControls>" +
                 "</Model>";
        }

        /// <summary>
        /// XML 生成控件 - 主要用于复制粘贴
        /// </summary>
        /// <param name="XML"></param>
        /// <param name="parentContainer">控件的父容器</param>
        /// <param name="model"></param>
        public static List<CtrlMngDesign> XMLToControls(string XML, ContainerHandler parentContainer, ModelDesign model)
        {
            List<CtrlMngDesign> list = new List<CtrlMngDesign>();
            if (XML.Length > 0)
            {
                System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                doc.LoadXml(XML);

                CtrlMngDesign ctrl;

                foreach (System.Xml.XmlNode XN in doc.DocumentElement.ChildNodes)
                {
                    ctrl = null;

                    switch (XN.Name.ToLower())
                    {
                        case "controls":
                            foreach (System.Xml.XmlNode xn in XN.ChildNodes)
                            {
                                ctrl = XMLToControl(xn, parentContainer, model);
                                list.Add(ctrl);
                            }
                            break;

                        case "comcontrols":
                            foreach (System.Xml.XmlNode xn in XN.ChildNodes)
                            {
                                ctrl = XMLToControl(xn, model.CtrlComContainerHandler, model);
                                list.Add(ctrl);
                            }
                            break;

                        default:
                            break;
                    }
                }
            }

            return list;
        }

        #region 私有方法

        /// <summary>
        /// 容器所有控件XML
        /// </summary>
        /// <param name="container"></param>
        /// <returns></returns>
        private static string ControlsToXML(ContainerHandler container)
        {
            string str = string.Empty;
            //设置控件偏移量
            int verticalScrollValue = 0;
            int horizontalScrollValue = 0;

            if (container.Container is DevExpress.XtraEditors.PanelControl)
            {
                verticalScrollValue = (container.Container as DevExpress.XtraEditors.PanelControl).VerticalScroll.Value;
                horizontalScrollValue = (container.Container as DevExpress.XtraEditors.PanelControl).HorizontalScroll.Value;
            }
            else if (container.Container is System.Windows.Forms.Form)
            {
                verticalScrollValue = (container.Container as System.Windows.Forms.Form).VerticalScroll.Value;
                horizontalScrollValue = (container.Container as System.Windows.Forms.Form).HorizontalScroll.Value;
            }

            foreach (CtrlMngDesign ctrl in container.Controls)
            {
                (ctrl.Ctrl as System.Windows.Forms.Control).Top += verticalScrollValue;
                (ctrl.Ctrl as System.Windows.Forms.Control).Left += horizontalScrollValue;
                str += "<Control id=\"" + ((ICtrlBase)ctrl.Owner).CtrlID + "\">" + ControlToXML(ctrl) + "</Control>";
            }

            return str;
        }

        /// <summary>
        /// 单个控件XML
        /// </summary>
        /// <param name="ctrl"></param>
        /// <returns></returns>
        private static string ControlToXML(CtrlMngDesign ctrl)
        {
            string str = string.Empty;

            if (ctrl.Owner is ICtrlContainer)
            {
                foreach (ContainerHandler container in ctrl.ContainerHandlerList)
                {
                    str += ControlsToXML(container);
                }
            }

            return "<Assembly>" + AssemblyToXML(ctrl) + "</Assembly>" +
                   "<Property>" + ((IXMLConvertor)ctrl.Owner).ToXML() + "</Property>" +
                   "<Controls>" + str + "</Controls>";
        }

        /// <summary>
        /// 控件的创建信息
        /// </summary>
        /// <param name="ctrl"></param>
        /// <returns></returns>
        private static string AssemblyToXML(CtrlMngDesign ctrl)
        {

            return "<Name>" + ctrl.Owner.GetType().ToString() + "</Name>" +
                   "<Class>" + ctrl.Owner.GetType().Name + "</Class>" +
                   "<AssemblyName>" + ctrl.Owner.GetType().Assembly.GetName().Name + "</AssemblyName>" +
                   "<Container>" + ctrl.ParentContainer.Container.Name + "</Container>";
        }

        private static CtrlMngDesign XMLToControl(System.Xml.XmlNode XN, ContainerHandler parentContainer, ModelDesign model)
        {
            System.Windows.Forms.Control ctrl = ControlBuilder.ControlNew(XN.FirstChild.ChildNodes[2].InnerText,XN.FirstChild.ChildNodes[0].InnerText, model, EDesignModeState.Design);

            if (ctrl != null && ctrl is ICtrlBase)
            {
                CtrlMngDesign ctrlMng = new CtrlMngDesign((ICtrlBase)ctrl, parentContainer, model);
                ((IXMLConvertor)ctrl).FromXML(XN.ChildNodes[1].ChildNodes);  //此处必须要先属性赋值 再添加（涉及到控件名称检测）
                parentContainer.Add(ctrlMng);

                if (ctrl is ICtrlContainer)
                {
                    ContainerHandler ch = null;

                    foreach (System.Xml.XmlNode cxn in XN.ChildNodes[2].ChildNodes)
                    {
                        ch = ctrlMng.GetContainerHandler(cxn.ChildNodes[0].ChildNodes[2].InnerText);
                        if (ch != null)
                        {
                            XMLToControl(cxn, ch, model);
                        }
                    }
                }

                return ctrlMng;
            }
            else
            {
                return null;
            }
        }

        #endregion 私有方法
    }
}